﻿using Dubbo.Config.Api;
using Spring.Context;
using Spring.Context.Support;
using Spring.Objects.Factory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Dubbo.Config.Spring
{
    public class ReferenceObject<T> : ReferenceConfig<T>, IInitializingObject, IFactoryObject, IApplicationContextAware, IDisposable
    {
        private IApplicationContext applicationContext;

        public IApplicationContext ApplicationContext
        {
            set
            {
                this.applicationContext = value;
                SpringExtensionFactory.AddApplicationContext(applicationContext);
            }
        }

        public bool IsSingleton { get { return true; } }

        public Type ObjectType { get { return typeof(T); } }

        public object GetObject()
        {
            return Get();
        }

        public void AfterPropertiesSet()
        {
            if (Application == null)
            {
                var applicationConfigMap = applicationContext == null ? null
                     : ObjectFactoryUtils.ObjectsOfTypeIncludingAncestors(applicationContext, typeof(ApplicationConfig), false, false);
                if (applicationConfigMap != null && applicationConfigMap.Count > 0)
                {
                    ApplicationConfig applicationConfig = null;
                    foreach (ApplicationConfig config in applicationConfigMap.Values)
                    {
                        if (config.IsDefault == null || config.IsDefault.Value)
                        {
                            if (applicationConfig != null)
                            {
                                throw new Exception("Duplicate application configs: " + applicationConfig + " and " + config);
                            }
                            applicationConfig = config;
                        }
                    }
                    if (applicationConfig != null)
                    {
                        Application = applicationConfig;
                    }
                }
            }

            var b = IsInit;
            //if (b == null && getConsumer() != null)
            //{
            //    b = getConsumer().isInit();
            //}
            if (b != null && b.Value)
            {
                GetObject();
            }
        }

        public void Dispose()
        {
            Destroy();
        }
    }
}
